
import { TypeDirection, TypeWidgetItem, TypeProvideFocus, TypeKeyDownParams, TypeBoxItem, TypeFocusState } from "../type";
import { queryWidgetByAreaAlgorithm, queryWidgetByShadowAlgorithm } from '../path/fecalc';
export class KeyEvents {
  constructor() {

  }
  getWidgetByList(widgetItem: TypeWidgetItem, key: TypeDirection, widgetList: (TypeWidgetItem | TypeBoxItem)[]) {
    const _wdiget = queryWidgetByShadowAlgorithm(widgetList, key as TypeDirection, widgetItem)
      || queryWidgetByAreaAlgorithm(widgetList, key as TypeDirection, widgetItem)
    return _wdiget
  }
  findNextFocus(_state: TypeFocusState, key: TypeDirection, widgetItem?: TypeWidgetItem) {
    if (!widgetItem) return ""
    let _wdiget: TypeWidgetItem | undefined
    //游离在盒子元素之外的元素列表
    const _list = _state.widgetList.filter((val) => !val.boxId)
    //与当前元素相邻的盒子元素列表
    const _nearestBoxItem = this.getWidgetByList(widgetItem, key as TypeDirection, _state.boxList)
    //如果当前元素是任意盒子内部的元素--取出相邻两个盒子的元素进行焦点计算
    if (!_wdiget && widgetItem?.boxId) {
      //两个盒子内部的元素
      const boxWidgetList: TypeWidgetItem[] = _state.widgetList.filter((val) => (val.boxId === widgetItem?.boxId || val.boxId === _nearestBoxItem?.uid))
      _wdiget = this.getWidgetByList(widgetItem, key as TypeDirection, [...boxWidgetList, ..._list])
    }
    //如果当前元素不在任意盒子内部-将与该元素相邻的盒子元素内的焦点取出来与其它游离的元素一起计算
    if (!_wdiget && !widgetItem?.boxId) {
      //盒子内部的元素
      const boxWidgetList: TypeWidgetItem[] = _state.widgetList.filter((val) => val.boxId === _nearestBoxItem?.uid)
      _wdiget = this.getWidgetByList(widgetItem, key as TypeDirection, [...boxWidgetList, ..._list])
      
    }
    // 按照顺序跳转
    if (!_wdiget && widgetItem.sequence) {
      const nowWidgetIndex = _state.widgetList.findIndex(val => val.uid === widgetItem?.uid)
      let idx = 0
      switch (key) {
        case "LEFT":
          idx = nowWidgetIndex - 1
          break;
        case "RIGHT":
          idx = nowWidgetIndex + 1
          break;
        default:
          break;
      }
      _wdiget = _state.widgetList[idx]
    }
    //普通跳转方式
    if (!_wdiget) {
      _wdiget = this.getWidgetByList(widgetItem, key as TypeDirection, _state.widgetList)
    }

    let _focusId = _wdiget?.uid
    if (_wdiget) {
      //获得scroll中的缓存焦点id，如果有那么直接聚焦至此ID
      if ((_wdiget.boxCacheId && _wdiget.boxCacheId !== widgetItem.boxCacheId) && _state.widgetList.find(val => val.uid === _wdiget?.boxCacheId) && !widgetItem.sequence) {
        _focusId = _wdiget.boxCacheId
      }
    }
    return _focusId || ""
  }
  onKeyMove(ev: KeyboardEvent, provide: TypeProvideFocus, params: TypeKeyDownParams) {
    const _state = provide.state
    //上下左右
    if (ev.keyCode === params.keyboard.LEFT || ev.keyCode === params.keyboard.RIGHT || ev.keyCode === params.keyboard.UP || ev.keyCode === params.keyboard.DOWN) {
      if (_state.widgetList.length < 1) return
      let widgetItem = _state.widgetList.find(v => v.uid === _state.focusId.value)
      if (!widgetItem) {
        provide.changeFocus(_state.widgetList[0].uid)
        widgetItem = _state.widgetList[0]
      }
      if (!widgetItem) {
        throw new Error("元素列表中未找到焦点")
      }
      if (typeof widgetItem.onMoveFocus === "function" && widgetItem.onMoveFocus(params.key) === false) return
      let _focusId = ""
      let _fegotoList: string[] = []
      if (ev.keyCode === params.keyboard.LEFT && _state.focusId.value === _state.nextWidget.widgetId) _focusId = _state.nextWidget.LEFT
      else if (ev.keyCode === params.keyboard.RIGHT && _state.focusId.value === _state.nextWidget.widgetId) _focusId = _state.nextWidget.RIGHT
      else if (ev.keyCode === params.keyboard.UP && _state.focusId.value === _state.nextWidget.widgetId) _focusId = _state.nextWidget.UP
      else if (ev.keyCode === params.keyboard.DOWN && _state.focusId.value === _state.nextWidget.widgetId) _focusId = _state.nextWidget.DOWN
      if (ev.keyCode === params.keyboard.LEFT) _fegotoList = widgetItem.goleft
      if (ev.keyCode === params.keyboard.RIGHT) _fegotoList = widgetItem.goright
      if (ev.keyCode === params.keyboard.UP) _fegotoList = widgetItem.goup
      if (ev.keyCode === params.keyboard.DOWN) _fegotoList = widgetItem.godown
      if (_fegotoList.length > 0) {
        _focusId = _state.widgetList.find(v => _fegotoList.find(val => v.uid === val))?.uid || ""
      }
      if (!_focusId) {
        _focusId = this.findNextFocus(provide.state, params.key as TypeDirection, widgetItem)
      }
      _focusId && provide.changeFocus(_focusId)
    }
  }
}